#ifndef PLAYSERVER_H
#define PLAYSERVER_H

// Libraries
#include "state.h"
#include "singleton.h"

// Forward Declarations
class CDatabase;
class ObjectManagerClass;
class InstanceClass;
class PacketClass;
class CGObject;
class PlayerClass;
class ServerBattleClass;

// Classes
class PlayServerState: public Singleton<PlayServerState>
{
	public:

		bool Init(bool _multiplayer);
		bool Close();

		void HandleConnect(ENetEvent *TEvent);
		void HandleDisconnect(ENetEvent *TEvent);
		void HandlePacket(ENetEvent *TEvent);

		void Update(u32 TDeltaTime);
		void DeleteObject(CGObject *TObject);

		void SendPacketToPeer(PacketClass *TPacket, ENetPeer *TPeer);

		u32 GetServerTime() const { return ServerTime; }

	private:
		void CreateDefaultDatabase();

		void HandleLoginInfo(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleCharacterListRequest(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleCharacterSelect(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleCharacterDelete(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleCharacterCreate(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleMoveCommand(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleBattleCommand(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleBattleFinished(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleInventoryMove(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleInventoryUse(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleInventorySplit(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleEventEnd(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleVendorExchange(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleSkillBar(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleSkillAdjust(PacketClass *TPacket, ENetPeer *TPeer);
		void HandlePlayerBusy(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleAttackPlayer(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleChatMessage(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleTradeRequest(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleTradeCancel(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleTradeGold(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleTradeAccept(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleTownPortal(PacketClass *TPacket, ENetPeer *TPeer);
		void HandleTraderAccept(PacketClass *TPacket, ENetPeer *TPeer);

		void SendPlayerPosition(PlayerClass *TPlayer);
		void SpawnPlayer(PlayerClass *TPlayer, int TNewMapID, int TEventType, int TEventData);
		void SendHUD(PlayerClass *TPlayer);
		void SendCharacterList(PlayerClass *TPlayer);
		void SendEvent(PlayerClass *TPlayer, int TType, int TData);
		void SendTradeInformation(PlayerClass *TSender, PlayerClass *TReceiver);

		void BuildTradeItemsPacket(PlayerClass *TPlayer, PacketClass *TPacket, int TGold);

		void RemovePlayerFromBattle(PlayerClass *TPlayer);

		CDatabase *Database;
		ObjectManagerClass *ObjectManager;
		InstanceClass *Instances;

		ENetHost *Connection;
		ENetPeer *Peer;
		ENetPeer SinglePeer;

		bool IsMultiplayer;

		u32 ServerTime;
};

#endif
